package com.xiashitech.agent.utils;

import com.xiashitech.agent.config.StartConfig;
import com.xiashitech.agent.instrumentation.base.context.TraceConst;
import com.xiashitech.interfaces.agent.dto.AgentConfigDTO;
import io.opentelemetry.javaagent.shaded.io.opentelemetry.api.baggage.Baggage;
import ognl.Ognl;

import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class UserMatchUtil {

    public static boolean isLoginToken(byte[] redisKey, Baggage baggage) {
        if(redisKey == null) {
            return false;
        }

        String logintoken = baggage.getEntryValue(TraceConst.XS_LOGIN_TOKEN);
        if (logintoken == null || logintoken.isEmpty()) {
            return false;
        }

        return new String(redisKey).contains(logintoken);
    }

    /**
     * 以token长度判断token有效性，至少为32个字符
     * @param token
     * @return
     */
    public static boolean judgeTokenLength32(String token) {
        if(token != null && !"".equals(token) && token.length() >= 32) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 根据传入的byte[]判断其中是否包含用户标识，byte[]转换后可以是单个字符串、json字符串或者对象
     * @param value
     * @return
     */
    public static boolean judgeContainUserId(byte[] value) {
        if(value == null || value.length == 0) {
            return false;
        }
        boolean isContainUserId = false;
        Object userObject = null;
        String jsonObj = new String(value);
        if(JsonUtil.isJson(jsonObj)) {
            userObject = JsonUtil.convertStringToObject(jsonObj,Object.class);
        } else {
            try(
                    ByteArrayInputStream inputStream = new ByteArrayInputStream(value);
                    ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
            ){
                userObject = objectInputStream.readObject();
            } catch (Throwable e) {
                StartConfig.throwableStackPrinter(e);
            }
        }
        String userIdPath = AgentConfigDTO.getConfig().getUseridpath().get(StartConfig.getParamValueFromKey(StartConfig.systemId));
        try {
            String userIdValue = String.valueOf(Ognl.getValue(userIdPath, userObject));
            if(userIdValue != null && !"".equals(userIdValue)) {
                isContainUserId = true;
            }
        } catch (Throwable e) {
            StartConfig.throwableStackPrinter(e);
        }
        return isContainUserId;
    }

    public static boolean judgeTokenValid(String token) {
        List<String> splitWordList = splitWord(token);
        return splitWordList.stream().anyMatch(keySplit -> judgeTokenLength32(keySplit));
    }

    public static List<String> splitWord(String keyOrValue) {
        List<String> matchList = new ArrayList();
        String regEx = "([`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~\\\\])*?([A-Za-z0-9\\-])*([`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~\\\\])*?";
        Pattern p = Pattern.compile(regEx);
        Matcher matcher = p.matcher(keyOrValue);
        while (matcher.find()) {
            if(matcher.group(0) == null || "".equals(matcher.group(0))) {
                continue;
            }
            matchList.add(matcher.group(0));
        }
        return matchList;
    }

    public static void getAllInterfaces(Class clazz,List<Class> interfaces) {
        if(clazz == null || interfaces == null || clazz == Object.class) {
            return;
        }
        if(clazz.getInterfaces().length > 0) {
            interfaces.addAll(Arrays.asList(clazz.getInterfaces()));
        }
        if(clazz.getSuperclass() != null) {
            getAllInterfaces(clazz.getSuperclass(),interfaces);
        }
    }
}
